package com.easymin.weixin.controller.h5.v3;

import com.google.common.base.Preconditions;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.common.api.Company;
import com.easymin.weixin.common.api.DaijiaApi;
import com.easymin.weixin.common.api.ErrandApi;
import com.easymin.weixin.common.api.PassengerApi;
import com.easymin.weixin.common.transport.Result;
import com.easymin.weixin.entity.WxAccount;
import com.easymin.weixin.entity.WxApplication;
import com.easymin.weixin.entity.WxBind;
import com.easymin.weixin.entity.passenger.Passenger;
import com.easymin.weixin.manager.WxAccountManager;
import com.easymin.weixin.manager.WxApplicationManager;
import com.easymin.weixin.manager.WxBindManager;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by shine on 15/9/14.
 */
@SuppressWarnings("all")
@Controller
@RequestMapping("h5/v3")
public class H5V3Controller {
  
  private static final Logger logger = LoggerFactory.getLogger(H5V3Controller.class);

  @Autowired
  private WxApplicationManager wxApplicationManager;

  @Autowired
  private WxAccountManager wxAccountManager;

  @Autowired
  private WxBindManager wxBindManager;

  @Autowired
  private RestTemplate restTemplate;

  @Autowired
  private PassengerApi passengerApi;

  @Autowired
  private DaijiaApi daijiaApi;

  @Autowired
  private ErrandApi errandApi;

  /**
   * 主页.
   * @param appKey 系统key
   * @param appid 微信应用Id
   * @param model model层
   * @param request 判断是否来自微信
   * @return String
   */
  @RequestMapping(value = {"", "/"})
  public String index(
      @RequestParam("appkey") String appKey,
      @RequestParam("appid") String appid,
      Model model,
      HttpServletRequest request) {

    model.addAttribute("appkey", appKey); //系统key
    model.addAttribute("appId", appid); //微信应用Id

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    WxAccount wxAccount = wxAccountManager.findBy(appid, wxApplication.getId());
    Preconditions.checkArgument(null != wxAccount, "appid错误");

    model.addAttribute("wx", wxAccount);

    if (StringUtils.isNotBlank(wxAccount.getAck())) {
      model.addAttribute("ack", wxAccount.getAck());
    }

    JSONObject services = daijiaApi.getServices(wxApplication.getAddress());
    int menu = 0;
    boolean daijia = services.getBooleanValue("daijia");
    if (daijia) {
      menu++;
    }
    boolean zhuanche = services.getBooleanValue("zhuanche");
    if (zhuanche) {
      menu++;
    }
    boolean paotui = services.getBooleanValue("paotui");
    if (paotui) {
      menu++;
    }

    model.addAttribute("daijia", daijia);
    model.addAttribute("zhuanche", zhuanche);
    model.addAttribute("paotui", paotui);
    model.addAttribute("menucount", menu);


    return "h5/v3/index";
  }

  /**
   * 获取服务信息.
   * @param appKey 系统key
   * @return JSONObject
   */
  @RequestMapping(value = "getServices")
  @ResponseBody
  public JSONObject getServices(@RequestParam("appkey") String appKey) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");


    return daijiaApi.getServices(wxApplication.getAddress());

  }

  /**
   * 代驾收费标准.
   * @param appkey 系统key
   * @param ack 区分公司
   * @param lat 纬度
   * @param lng 经度
   * @param passengerId 客户id
   * @return JSONObject
   */
  @RequestMapping("queryArea")
  @ResponseBody
  public JSONObject queryArea(
      @RequestParam("appkey") String appkey,
      @RequestParam(required = false, value = "ack") String ack,
      @RequestParam("lat") Double lat,
      @RequestParam("lng") Double lng,
      @RequestParam(required = false, value = "passengerId") Long passengerId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appkey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    Long passengerCompanyId = null;

    if (passengerId != null) {
      Passenger passenger = passengerApi.findById(passengerId, appkey);
      if (null != passenger) {
        passengerCompanyId = passenger.getCompanyId();
      }
    }

    JSONObject json = daijiaApi.getCompanyByAppKey(
        wxApplication.getAddress(), ack, passengerCompanyId, lng, lat);
    Long areaId = json.getLong("areaId");

    return daijiaApi.findChargeStartTime(wxApplication.getAddress(), areaId);
  }

  /**
   * 查询专车收费标准.
   * @param appkey 系统key
   * @param carTypeId 车型id
   * @return JSONObject
   */
  @RequestMapping("queryZhuanArea")
  @ResponseBody
  public JSONObject queryZhuanArea(
      @RequestParam("appkey") String appkey,
      @RequestParam(required = false, value = "ack") String ack,
      @RequestParam(required = false, value = "carTypeId") Long carTypeId,
      @RequestParam("lat") Double lat,
      @RequestParam("lng") Double lng,
      @RequestParam(required = false, value = "passengerId") Long passengerId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appkey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    JSONArray jsonArray = daijiaApi.getCarTypes(
        wxApplication.getAddress(), ack, passengerId, lng, lat);

    Long areaId = null;
    for (int i = 0; i < jsonArray.size(); i++) {
      if (carTypeId != null 
          && carTypeId.equals(jsonArray.getJSONObject(i).getLongValue("carTypeId"))) {
        areaId = jsonArray.getJSONObject(i).getLongValue("areaId");
      }

    }

    return daijiaApi.findChargeStartTime(wxApplication.getAddress(), areaId);
  }

  /**
   * 查询跑腿收费标准.
   * @param appkey 系统key
   * @param ack 区分公司
   * @param errandTypeId 类型id
   * @param passengerId 客户id
   * @return JSONObject
   */
  @ResponseBody
  @RequestMapping("queryErrandArea")
  public JSONObject queryErrandArea(
      @RequestParam("appkey") String appkey,
      @RequestParam(required = false, value = "ack") String ack,
      @RequestParam(required = false, value = "errandTypeId") Long errandTypeId,
      @RequestParam(required = false, value = "passengerId") Long passengerId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appkey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    Long passengerCompanyId = null;

    if (passengerId != null) {
      Passenger passenger = passengerApi.findById(passengerId, appkey);
      if (null != passenger) {
        passengerCompanyId = passenger.getCompanyId();
      }
    }

    JSONArray jsonArray = errandApi.queryTypes(passengerCompanyId, appkey);
    Long areaId = null;
    for (int i = 0; i < jsonArray.size(); i++) {
      if (errandTypeId != null 
          && errandTypeId.equals(jsonArray.getJSONObject(i).getLongValue("id"))) {
        areaId = jsonArray.getJSONObject(i).getLongValue("areaId");
      }
    }

    return daijiaApi.findChargeStartTime(wxApplication.getAddress(), areaId);
  }


  /**
   * 获取服务内容.
   * @param appKey 系统key
   */
  @RequestMapping(value = "getAgreement")
  public ResponseEntity<String> getAgreement(
      @RequestParam("appkey") String appKey) throws Exception {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    String aggrement = daijiaApi.getAgreement(wxApplication.getAddress());

    ResponseEntity<String> responseEntity = new ResponseEntity(aggrement, HttpStatus.OK);

    return responseEntity;
  }

  /**
   * 检查微信绑定.
   * @param appKey 系统key
   * @param appid 微信应用id
   * @param phone 手机号
   * @param openId 微信id
   * @return JSONObject
   */
  
  @ResponseBody
  @RequestMapping(value = "checkBind", method = RequestMethod.POST)
  public JSONObject checkBind(
      @RequestParam("appkey") String appKey,
      @RequestParam("appid") String appid,
      @RequestParam("phone") String phone,
      @RequestParam(required = false, value = "openId") String openId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    WxAccount wxAccount = wxAccountManager.findBy(appid, wxApplication.getId());
    Preconditions.checkArgument(null != wxAccount, "appid错误");

    boolean isBind = false;
    boolean isSend = false;

    if (StringUtils.isNotBlank(openId)) {

      WxBind wxBind = wxBindManager.findOne(phone, openId, appKey);
      if (null != wxBind) {
        isBind = true;
      }
    }

    if (!isBind) { //未绑定
      //发送短信
      String response = daijiaApi.sendVcode(wxApplication.getAddress(), phone);

      JSONObject jsonObject = JSON.parseObject(response);

      if (jsonObject.getBooleanValue("success")) {
        isSend = true;
      } else if (jsonObject.getInteger("object") != null 
          && jsonObject.getInteger("object").intValue() > 0) {

        isSend = true;
      }

    }


    JSONObject result = new JSONObject();
    result.put("isBind", isBind);
    result.put("isSend", isSend);

    return result;
  }

  /**
   * 验证验证码是否正确,并且通过微信操作则绑定账号.
   * @param appKey 系统key
   * @param appid 微信应用id
   * @param phone 手机号
   * @param openId 微信id
   * @param vcode 验证码
   * @param city 城市
   * @return JSONObject
   */
  @ResponseBody
  @RequestMapping(value = "checkCode", method = RequestMethod.POST)
  public JSONObject checkCode(
      @RequestParam("appkey") String appKey,
      @RequestParam("appid") String appid,
      @RequestParam("phone") String phone,
      @RequestParam(required = false, value = "openId") String openId,
      @RequestParam("vcode") String vcode,
      @RequestParam("city") String city) {
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    WxAccount wxAccount = wxAccountManager.findBy(appid, wxApplication.getId());
    Preconditions.checkArgument(null != wxAccount, "appid错误");

    //验证验证码是否正确
    String reponse = daijiaApi.validateCode(wxApplication.getAddress(), phone, vcode);
    JSONObject jsonObject = JSON.parseObject(reponse);

    JSONObject result = new JSONObject();


    if (jsonObject.getBooleanValue("success")) {

      //获取用户id
      Passenger passenger = passengerApi.findOne(phone, appKey);

      if (null == passenger) {
        //创建用户
        passenger = new Passenger();
        passenger.setPhone(phone);
        passenger.setAppKey(appKey);
        if (StringUtils.isNoneBlank(openId)) {
          passenger.setChannel_name("微信预约");
        } else {
          passenger.setChannel_name("网站预约");
        }
        passenger.setName("先生/女士");
        passenger.setAllowOverdraw(false);

        //查询公司信息
        Company company = null;

        String response = daijiaApi.findCompany(wxApplication.getAddress(), city);
        JSONObject jo = JSON.parseObject(response);

        JSONArray jsonArray = jo.getJSONArray("others");

        if (null == jsonArray || jsonArray.size() == 0) {
          //没有分公司
          JSONObject jsonObject1 = jo.getJSONObject("main");
          company = JSON.parseObject(jsonObject1.toString(), Company.class);
        } else {
          //随机选择一个公司
          Random random = new Random();
          int randomPos = random.nextInt(jsonArray.size());
          JSONObject jsonObject1 = jsonArray.getJSONObject(randomPos);
          company = JSON.parseObject(jsonObject1.toString(), Company.class);
        }

        passenger.setCompanyId(company.getId());
        passenger.setCompanyName(company.getAbbreviation()); //使用简称
        passenger = passengerApi.create(passenger, appKey);
        daijiaApi.newPassengerActivity(wxApplication.getAddress(), passenger.getId());

      }
      //验证成功
      if (StringUtils.isNoneBlank(openId)) {
        wxBindManager.bind(appKey, phone, openId, passenger.getId()); //绑定账号
      }

      result.put("passengerPhone", passenger.getPhone());
      result.put("passengerId", passenger.getId());
      result.put("success", true);
      result.put("message", "验证成功");


    } else {
      //验证失败
      result.put("success", false);
      result.put("message", jsonObject.getString("message"));
    }

    return result;

  }

  /**
   * 查询指定司机信息.
   * 
   * @param appKey 系统key
   * @param driverId 司机id
   * @return JSONObject
   */
  @ResponseBody
  @RequestMapping("findDriver")
  public JSONObject findDriver(
      @RequestParam("appkey") String appKey,
      @RequestParam("driverId") Long driverId) {

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    return daijiaApi.findDriver(wxApplication.getAddress(), driverId);
  }

  /**
   * 获取openId.
   * @param appKey 系统key
   * @param code 编码
   * @param appid 微信应用id
   * @return Result
   */
  @ResponseBody
  @RequestMapping(value = "authInfo", method = RequestMethod.GET)
  public Result authInfo(
      @RequestParam("appKey") String appKey,
      @RequestParam("code") String code,
      @RequestParam("appid") String appid) {

    Preconditions.checkArgument(StringUtils.isNotBlank(appKey), "appKey不能为空");
    Preconditions.checkArgument(StringUtils.isNotBlank(code), "code不能为空");

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    WxAccount wxAccount = wxAccountManager.findBy(appid, wxApplication.getId());
    Preconditions.checkArgument(null != wxAccount, "appId错误");


    StringBuilder builder = new StringBuilder();
    builder.append("https://api.weixin.qq.com/sns/oauth2/access_token");
    builder.append("?appid=").append(wxAccount.getWxappId());
    builder.append("&secret=").append(wxAccount.getAppsecret());
    builder.append("&code=").append(code);
    builder.append("&grant_type=authorization_code");

    Result<String> result = new Result<>(-2, "错误", null);

    try {

      ResponseEntity<String> responseEntity = 
          restTemplate.getForEntity(URI.create(builder.toString()), String.class);

      if (responseEntity.getStatusCode().is2xxSuccessful()) {
        JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());

        if (jsonObject.containsKey("openid")) {
          String openid = jsonObject.getString("openid");
          result.setCode(0);
          result.setMessage("成功");
          result.setData(openid);
        } else {
          String errmsg = jsonObject.getString("errmsg");
          result.setCode(-1);
          result.setMessage(errmsg);
        }
      }
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      String errmsg = ex.getMessage();
      result.setCode(-2);
      result.setMessage(errmsg);
    }

    return result;
  }


  /**
   * 发送验证码.
   * @param appkey 系统key
   * @param phone 手机号
   * @return JSONObject
   */
  @ResponseBody
  @RequestMapping(value = "sendVCode", method = RequestMethod.GET)
  public JSONObject sendVCode( HttpServletRequest request,
      @RequestParam("appkey") String appkey,
      @RequestParam("phone") String phone) {

    logger.error("错误接口:{}",request.getRemoteAddr()+","+request.getRemotePort());
    System.out.println("H5V3:"+request.getRemoteAddr()+","+request.getRemotePort());
    Preconditions.checkArgument(StringUtils.isNotBlank(appkey), "appkey不能为空");
    Preconditions.checkArgument(StringUtils.isNotBlank(phone), "电话号码不能为空");

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appkey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    String response = daijiaApi.sendVcode(wxApplication.getAddress(), phone);

    JSONObject jsonObject = JSON.parseObject(response);

    return jsonObject;
  }

  /**
   * 查询微信绑定信息.
   * @param appKey 系统key
   * @param openId 微信id
   * @return Result
   */
  @ResponseBody
  @RequestMapping(value = "findWxBind", method = RequestMethod.GET)
  public Result findWxBind(
      @RequestParam("appKey") String appKey,
      @RequestParam("openId") String openId) {

    Preconditions.checkArgument(StringUtils.isNotBlank(appKey), "appKey不能为空");
    Preconditions.checkArgument(StringUtils.isNotBlank(openId), "openId");

    WxApplication wxApplication = wxApplicationManager.findByAppKey(appKey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    Result result = new Result(-1, "请稍后再试", null);
    try {
      WxBind wxBind = wxBindManager.findByOpenIdAndAppKey(openId, appKey);
      if (null != wxBind) {
        result.setCode(0);
        result.setData(wxBind);
      }
    } catch (Exception ex) {
      logger.error(ex.getMessage());
      result.setCode(-2);
      result.setMessage("内部服务器错误:" + ex.getMessage());
    }

    return result;

  }


  /**
   * 查询微信广告.
   * @param appkey 系统key
   * @param ack 区分公司
   * @param lat 纬度
   * @param lng 经度
   * @param passengerId 客户id
   * @return JSONObject
   */
  @ResponseBody
  @RequestMapping(value = "advs", method = RequestMethod.GET)
  public JSONObject advs(
      @RequestParam("appkey") String appkey,
      @RequestParam(required = false, value = "ack") String ack,
      @RequestParam("lat") Double lat,
      @RequestParam("lng") Double lng,
      @RequestParam(required = false, value = "passengerId") Long passengerId) {
    WxApplication wxApplication = wxApplicationManager.findByAppKey(appkey);
    Preconditions.checkArgument(null != wxApplication, "appKey错误");

    Long passengerCompanyId = null;

    if (passengerId != null) {
      Passenger passenger = passengerApi.findById(passengerId, appkey);
      if (null != passenger) {
        passengerCompanyId = passenger.getCompanyId();
      }
    }

    JSONObject compay = daijiaApi.getCompany(
        wxApplication.getAddress(), ack, passengerCompanyId, lng, lat);
    Long companyId = compay.getLong("data"); //选择的公司信息

    JSONObject jsonObject = daijiaApi.getAdvertisement(wxApplication.getAddress(), companyId);

    jsonObject.put("address", wxApplication.getAddress());

    return jsonObject;
  }

}
